<template>
  <el-upload
    class="upload"
    :class="className"
    :action="params.action || action"
    :accept="params.accept || '.jpg,.png'"
    :headers="headers"
    :data="params.data"
    :disabled="disabled"
    :show-file-list="showFileList"
    :with-credentials="true"
    :before-upload="beforeUpload"
    :on-success="onSuccess"
    :on-remove="onRemove"
    :on-error="onError"
    :on-progress="onProgress"
    :http-request="httpRequest"
  >
    <slot>
      <i class="el-icon-plus"></i>
    </slot>
  </el-upload>
</template>

<script>
export default {
  name: 'Upload',
  props: {
    params: {
      type: Object,
      default: () => ({
        action: '#',
        accept: ''
      })
    },
    className: {
      type: String,
      default: ''
    },
    showFileList: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      action: `${process.env.VUE_APP_BASE_API}/upload/uploadImg`,
      disabled: false,
      fileInfo: {},
      isImage: null // 文件是否为图片类型
    }
  },
  computed: {
    headers () {
      return {
        token: ''
      }
    }
  },
  methods: {
    validateImage (file) {
      return new Promise((resolve, reject) => {
        const URL = window.URL || window.webkitURL
        const src = URL.createObjectURL(file)
        const img = new Image()
        img.src = src
        img.onload = () => {
          this.fileInfo[file.uid] = {
            file,
            width: img.width,
            height: img.height,
            name: file.name,
            type: file.type,
            size: file.size
          }
          return resolve()
        }
      })
    },
    async beforeUpload (file) {
      console.log('file: ', file)
      const is = file.type.indexOf('image') !== -1
      await this.validateImage(file)
      if (is) {
        this.disabled = true
        this.$emit('before-upload')
      }
      return is
    },
    onSuccess (res) {
      console.log('success: ', res)
      this.disabled = false
      if (res.success) {
        let data = res.data
        if (Object.prototype.toString.call(data) === '[object Array]') {
          data = data[0]
        }
        this.$emit('on-success', data)
      } else {
        const message = res.msg || '抱歉, 请求出错'
        this.$message({
          message,
          type: 'error',
          duration: 5000
        })
        this.onError(...arguments)
      }
    },
    onError () {
      this.$emit('on-error', ...arguments)
    },
    onRemove () {
      this.$emit('on-remove', ...arguments)
    },
    onProgress (event) {
      this.$emit('on-progress', ...arguments)
    },
    // 图片转base64
    pic2base64 (file) {
      return new Promise((resolve, reject) => {
        const fileReader = new FileReader()
        fileReader.readAsDataURL(file)
        fileReader.onload = function (e) {
          return resolve(e.target.result)
        }
        fileReader.onerror = function (e) {
          return resolve(false)
        }
      })
    },
    // 自定义上传
    async httpRequest ({ file }) {
      const fileInfo = this.fileInfo[file.uid]
      const {
        file: fileBase,
        ...fileBaseInfo
      } = fileInfo
      const picBase64 = await this.pic2base64(file)
      return picBase64 ? {
        msg: '成功',
        success: 200,
        data: {
          url: picBase64,
          ...fileBaseInfo
        }
      } : {
        msg: '图片读取失败',
        success: 0,
        data: {
          url: ''
        }
      }
    }
  }
}
</script>

<style lang="less" scoped>
.upload {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  // background-color: #fbfdff;
  // border: 1px dashed #c0ccda;
  // border-radius: 6px;
  box-sizing: border-box;
  .el-icon-plus {
    font-size: 28px;
    color: #8c939d;
  }
}
</style>